
require 'uri'
require 'erb'
require 'time'
require 'thread'
require 'stringio'
require 'ostruct'
require 'optparse'
require 'delegate'
require 'rubygems'
require 'active_record'
require 'logger'
require 'uuid'
require 'date'
require 'parsedate'
require "net/smtp"
require 'pp'

# global config
# TODO not really happy with global state ; see below
@@debuglog = false
@@debug = 1
@@sitename = "appwiki"
@@sethostpath = "#{@@sitename}"
@@sethostname = "#{@@sitename}.com"
@@forcehostname = nil # a hack to pretend to always see a given dns name.
@@server_port = 80
@@server_ip = '127.0.0.1'
@@debuglogger= nil

# Global Logging
# TODO not totally happy with these global methods
def logmsg(msg)
  @@debuglogger.info(msg) if @@debuglogger
end

def puts(msg)
  logmsg(msg) if @@debuglog
  print "#{msg}\n" if !@@debuglog
end

class Base < OpenStruct
  # see http://www.ruby-doc.org/stdlib/libdoc/ostruct/rdoc/index.html
  # TODO put state here instead?

  def parse_args
    # see http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html
    options = OptionParser.new do |opts|
      opts.banner = "Usage: boot.rb [options]"
      opts.separator ""
      opts.separator "Specific options:"
      opts.on("-p","--port PORTNUMBER","Optionally specify a port other than 80") do |arg|
        @@server_port = arg.to_i
      end
      opts.on("-i","--ip HOSTNAME","Optionally specify an ip other than 127.0.0.1") do |arg|
        @@server_ip = arg.to_i
      end
      opts.on("-n","--name","Optionally specify name other than 'appwiki'") do |arg|
        @@sitename = arg.to_i
      end
      opts.on("-h","--host","Optionally specify hostname other than 'appwiki.com'") do |arg|
        @@sethostpath = "#{arg}"
        @@sethostname = "#{arg}.com"
        # TODO we should be able to set the domain properly
      end
      opts.on("-d","--debug","Set debug level (default 0)") do |arg|
        @@debug = arg.to_i
      end
      opts.on("--h","--help","Show this message") do
        puts opts
        exit
      end
      opts.on_tail("--version","Show version") do
        puts "Version 0.3"
        exit
      end
    end
    options.parse!(ARGV)
  end

  def start_logging
    # before open active record or loading routes
    if @@debuglog
      log_stream = File.open("#{@@sitename.code.log}", 'a')
      STDOUT.reopen(log_stream)
      log = Logger.new log_stream
      log.level = Logger::DEBUG
      ActiveRecord::Base.logger = log
      @@debuglogger = log
    end
  end

  def open_activerecord
    # after load config
    # TODO allow set of activerecord name/pass properly
    ActiveRecord::Base.establish_connection({
      :adapter => "postgresql",
      :database => "#{@@sitename}",
      :username => "#{@@sitename}",
      :password => "#{@@sitename}",
      :host => "127.0.0.1",
      :port => 5432
    })
    puts 'opened'
  end

  def load_routes
    # after loading state and after active record { since it may use it }
    load "#{@@sethostpath}/routes.rb"
  end

  def boot
    parse_args
    start_logging
    open_activerecord
    load_routes
    load 'appwiki/base/base_webrick.rb'
    BaseServer.run
  end

end
